package com.supreme.studyserver.component;

import com.supreme.studyserver.service.noinject.PrintService;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class ProxyFactoryBeanConfig {

    /**
     * ProxyFactoryBean
     * @return
     */
    @Bean
    public ProxyFactoryBean printServiceProxy() {
        final PrintService printService = new PrintService();

        final ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
        proxyFactoryBean.setTarget(printService);

        proxyFactoryBean.addAdvice((MethodInterceptor) methodInvocation -> {
            System.out.println("proxyFactoryBefore ==>");
            final Object proceed = methodInvocation.proceed();
            System.out.println("proxyFactoryAfter ==>");
            return proceed;
        });

        return proxyFactoryBean;
    }

    /**
     * BeanNameAutoProxyCreator
     * @return
     */
    @Bean
    public MethodInterceptor printFirstAroundAdvice() {
        return methodInvocation -> {
            System.out.println("proxyFirstBefore ==>");
            final Object proceed = methodInvocation.proceed();
            System.out.println("proxyFirstAfter ==>");
            return proceed;
        };
    }

    @Bean
    public MethodInterceptor printSecondAroundAdvice() {
        return methodInvocation -> {
            System.out.println("proxySecondBefore ==>");
            final Object proceed = methodInvocation.proceed();
            System.out.println("proxySecondAfter ==>");
            return proceed;
        };
    }

    @Bean
    public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
        BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
        beanNameAutoProxyCreator.setBeanNames("authService");
        beanNameAutoProxyCreator.setInterceptorNames("printFirstAroundAdvice", "printSecondAroundAdvice");
        beanNameAutoProxyCreator.setProxyTargetClass(true);
        return beanNameAutoProxyCreator;
    }

    /**
     * DefaultAdvisorAutoProxyCreator
     * @return
     */
    /*@Bean
    public DefaultPointcutAdvisor defaultPointcutAdvisor() {
        NameMatchMethodPointcut nameMatchMethodPointcut = new NameMatchMethodPointcut();
        nameMatchMethodPointcut.addMethodName("showUser");

        DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
        defaultPointcutAdvisor.setPointcut(nameMatchMethodPointcut);
        defaultPointcutAdvisor.setAdvice((MethodInterceptor) methodInvocation -> {
            System.out.println("proxyPointcutBefore ==>");
            final Object proceed = methodInvocation.proceed();
            System.out.println("proxyPointcutAfter ==>");
            return proceed;
        });

        return defaultPointcutAdvisor;
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        return defaultAdvisorAutoProxyCreator;
    }*/
}
